
import Pack from './basics/Pack.js'
import Row from './basics/Row.js'
import File from './basics/File.js'
import  Block from './basics/Block.js'
import     RunOrderFile    from './run/RunOrderFile.js'
export default class Trans{
    constructor(){
        this.pack=new Pack();

        this.runStack=[];
    }

    /**
     *  参数都是 buff
     * @param dataRow
     * @param dataBlock
     * @param linkRow
     */
    loadData(data ){
        this.pack.loadData(data)
        //导入之后，需要判断一下，1里面有没有数据，如果没有添加一下
        /*    let  square=   this.pack.findData(1,0,null,null);
            if(!square){
                this.pack.addData(1,null,null,new Block()) // 虚 块 添加 square
            }*/
    }

    outData(){
      let buff=this.pack.outData();
      return  buff;
    }

    /**
     * 初始化
     */
    init(){
        this.pack=new Pack();
        // this.addFile(); //目录 可能也不需要、 、
        // 字初始化
        this.pack.addData(null,null,null,new File()) //实  块
        this.pack.addData(null,null,null,new File()) //虚  块
        this.pack.addData(1,null,null,new Block()) // 虚 块 添加 square
        // 添加文件可以单独分析
      //  this.addFile();// 意思 块
        //程序不需要初始化，直接添加文件
        //this.addFile();// 程序
    }
 /**
  *通常是链接
  */
    addEmpty(row,emptyId){
        if(emptyId){
            return  this.pack.addData(1,0,emptyId,row)
        }
          return  this.pack.addData(1,0,null,row)
     }

    /**
     *
     * @param row
     * @param func
     * @param resType  Default empty  id
     * @returns {*}
     */
    findEmptyId(row,func,resType){
        if(resType){
            this.resEmptyType=resType;
        }else {
            this.resEmptyType='empty';
        }
        if(row){
           this.emptyRow=row;
        }else {
            this.emptyRow=new Row(null,null,null,null);
        }
        if(func){
            return this.pack.findData(1,0,null,func)
        }
        return this.pack.findData(1,0,null,this.empthDefaultFunc.bind(this))
    }
    empthDefaultFunc(FileId,BlockId,RowId,dataThis){
        let word=this.emptyRow;

        for(let n=0;n<dataThis.list.length;n++){
            let row=  dataThis.list[n];
            let res=[];
            if(word.find(1)===null||row.isValue(1,word.find(1)) ) {
                res.push(1)
            }
            if(word.find(2)===null||row.isValue(2,word.find(2))  ){
                res.push(1)
            }
            if(word.find(3)===null||row.isValue(3,word.find(3)) ){
                res.push(1)
            }
            if(word.find(4)===null||row.isValue(4,word.find(4))  ){
                res.push(1)
            }
            if(res.length==4){
                if(this.resEmptyType=='empty') {
                    return row;
                }
                return n;
            }
        }
        return null;

    }
    /**
     * 添加一个实体
     */
    addReal(row,realId){
        if(!realId){
            realId=  this.pack.addData(0,null,null,new Block());
        }
         this.pack.addData(0,realId,null , row);
        return realId;
    }

    delIdea(fileId,realId,rowId,row){
        this.pack.addData(0,realId,rowId , row);
    }

    /**
     *
     * @param row
     * @param func
     * @param resType
     * @returns {*}
     */
    findReal(row,realId,func,resType){
        if(realId!=null&&typeof(realId) != "undefined"){
            this.realId=realId;
            return this.pack.findData(0,null,null,this.realDefaultFunc.bind(this))
        }
        if(resType){
            this.resRealType=resType;
        }else {
            this.resRealType='real';
        }
        if(row){
            this.realRow=row;
        }else {
            this.realRow=new Row(null,null,null,null);
        }
        if(func){
            return this.pack.findData(1,0,null,func)
        }
         return this.pack.findData(0,null,null,this.realDefaultFunc.bind(this))
    }
    realByIdFunc(FileId,BlockId,RowId,dataThis){
        let   realId=this.realId;
        return dataThis.list[realId];
    }

    realDefaultFunc(FileId,BlockId,RowId,dataThis){
        let word=this.realRow;
       let realId= this.realId;
        if(realId!=null){
            this.realId=null;
           return  dataThis.list[realId];
        }
        for(let n=0;n<dataThis.list.length;n++){
            let square=  dataThis.list[n];
            for(let l=0;l<square.list.length;l++){
                let row=square.list[l];
                let res=[];
                if(row.isValue(1,word.find(1))){
                    res.push(1)
                }
                if(row.isValue(2,word.find(2))){
                    res.push(2)
                }
                if(row.isValue(3,word.find(3)) ){
                    res.push(3)
                }
                if(row.isValue(4,word.find(4))){
                    res.push(4)
                }
                if(res.length==4){
                    if(this.resRealType=='real') {
                        return square;
                    }
                    return l;
                }
            }
        }
        return null;

    }
    /**
     * 通过 字查找 squareId
     */
    findBlockIdByWord(FileId,BlockId,RowId,dataThis){
        let word=this.word;
        for(let n=0;n<dataThis.list.length;n++){
            let square=  dataThis.list[n];
             for(let l=0;l<square.list.length;l++){
                  let row=square.list[l];
                  if(row.isValue(1,word) && row.isValue(4,2)){
                     return n;
                  }
             }
        }
        return null;
    }

    /**
     * 添加字   的关键 2
     */
    addWord(word){
        // 查找 代表字的意思
        //如果没有 添加
         this.word=word;
        let squareId = this.pack.findData(0,null,null,this.findBlockIdByWord.bind(this))
        if(squareId===null){
            squareId=  this.pack.addData(0,null,null,new Block());
           this.pack.addData(0,squareId,null , new Row( word,2));

        }
        return squareId;

    }
    /**
    /**
     *  查找意 根据 多个字的id
     */
    findIdeaByWordIds(FileId,BlockId,RowId,dataThis){


        let wordIds=this.wordIds;

        for(let n=0;n<dataThis.list.length;n++){
            let square=  dataThis.list[i];
            let resis=[];
            for(let l=0;l<square.list.length;l++){
                let row=square[l];
                if(row.isValue(1,wordIds[l]) && row.isValue(4,3)){
                    resis.push( i);
                }
            }
            if(resis.length==wordIds.length){
                return i;
            }
        }
    }

    /**
     *  添加 词
     *  3
     */
    addWrods(wordIdA,wordIdB){
       let words= new Row( wordIdA,wordIdB,null,3)
        let row= this.findEmptyId(words)
        if(!row){
            let reodId= this.addReal(words);
            let words1= new Row( wordIdA,wordIdB,reodId,3)
            this.addEmpty(words1);
            row=words1;
        }
       return row;
    }

    findWrods(wordIdA,wordIdB,reodId){
        if(reodId){
            let  real= this.findReal(null,reodId);
        }
        let words= new Row( wordIdA,wordIdB,null,3)
        return this.findEmptyId(words);
    }

    /**
     *
     * @param inpoutData
     * @param projectData
     * @returns {*}
     */
    run(inpoutData,projectData){
        //

/*
 三个字的处理逻辑
    如果，两个字成词之后，查找第三个字和第四个字是不是一个词。如此循环到特殊字或者结束。
    如果，有剩余一个字，先前查找有三个字可以组合的。
    注意动词 找上  形容字 大小
    两个非特殊字可以组成一个词。
    姓也是特殊字。
    姓后面可以把两个不是词的字组合成一个名词

    四个字的处理逻辑
    如果两个词是一个名词，做一个标记
    复姓 按三个字的逻辑处理
    如果三个字不是一个词，做一个特殊标记。
 */

        //查找每个字是否有特殊标记 是否是 程序标记 形容词

        return inpoutData;
    }


        ideaRun(wordIds){
            let _this=this;
            _this.  commsList=new File();
            _this.symbolList=new File();
            let wordsList=  _this.sortRun(wordIds );
        //    let i=_this.analysisRun(wordsList);

            return wordsList;
        }

    /**
     *分词
     */
    sortRun(wordIds){
        let _this=this;
        let signs=[]
        let field='31' ; //转换
        let act='34' ; //分词 field,act,
        let noun='35'; //名词
        let speech='33'; //词
        let symbol='42';//符号
        let id=0;
        for(let i=0;i<wordIds.length;i++,id++){

            let wordIdA=wordIds[i];
            let wordIdB=wordIds[i+1];

            let wordSign= _this.findSign(wordIdA)

            //两个字一样
            if(wordIds[i]==wordIds[i+1]){
                let wordIdz=wordIds[i];
                let list=[];
                while (wordIdA==wordIdz) {
                    list.push(wordIdA)
                    i++;
                    wordIdA=wordIds[i];
                }
                i--;
                signs.push({id:id,type:1,remarks:"词ID:重复词",wordIdList:list,wordIdKey:wordIdA })
                continue
            }


            let wordsId=_this.findWrodsId(wordIdA,wordIdB)
            if(wordsId){
                let words= _this.findSign(wordsId.find(3))
                if(_this.isSign(words,field,act,speech)){

                    let wordIdC=wordIds[i+2];
                    let isWords3=_this.findWrodsId(wordIdB,wordIdC)
                    let isWords3B=false;
                   if (isWords3){
                       let wordSign4= _this.findSign(wordIdC)
                      if(_this.isSign(wordSign4,field,act,speech)||_this.isSign(wordSign4,field,act,noun))   isWords3B=true
                    }
                    let wordSign4= _this.findSign(wordIdC)

                    if(isWords3B||_this.isSign(wordSign4,field,act,noun)){
                        let list=[wordIdA,wordIdB,wordIdC];
                        signs.push({id:id,type:4,remarks:"词ID:words3",wordIdList:list,wordIdKey:wordIdC,wordsId:wordIdC })
                        i=i+2;
                        continue
                    }
                    let list=[wordIdA,wordIdB];
                    signs.push({id:id,type:3,remarks:"词ID:words2",wordIdList:list,wordsId:wordsId.find(3)})
                    i++;
                    continue
                }

            }

            /**
             * 如果字符有特殊标记
             */

            if(_this.isSign(wordSign,field,act,symbol)){
                //遇到特殊标记开始检查栈数据是否完整。
                //检查清空栈

                switch(wordSign) {
                    //数字
                    case '1':

                        while (wordSign!=数字) {
                            id.push(wordId)
                            i++;
                            wordId=wordIds[i];
                            wordSign= _this.findSign(wordId)
                        }
                        signs.push({id:id,remarks:数字})
                        i--;
                        break;
                    case '1': //标点符号

                        while (wordSign!=数字) {
                            id.push(wordId)
                            i++;
                            wordId=wordIds[i];
                            wordSign= _this.findSign(wordId)
                        }
                        signs.push({id:id,remarks:数字})
                        i--;
                        break;
                    case '1'://特殊字符

                        while (wordSign!=数字) {
                            id.push(wordId)
                            i++;
                            wordId=wordIds[i];
                            wordSign= _this.findSign(wordId)
                        }
                        signs.push({id:id,remarks:数字})
                        i--;
                        break
                    default:
                      let  list=[wordIdA];
                        signs.push({id:id,type:7,remarks:'标记',wordIdList:list,wordIdKey:wordIdA})
                        break
                }
                continue
            }
            let wordBSign= _this.findSign(wordIdB)
            /**
             * 检查 wordIdB 是不是有没有特殊标记B
             */
            if(_this.isSign(wordBSign,field,act)){
               /* let isStack=this.checkStack(stack);
                if(isStack){
                    heap.push(stack);
                    stack=[];
                }*/
                let list=[wordIdA];
                signs.push({id:id,type:6,remarks:'剩字',wordIdList:list,wordIdKey:wordIdA})
                  list=[wordIdB];
                signs.push({id:id,type:7,remarks:'标记',wordIdList:list,wordIdKey:wordIdA})
                i++;
                continue
            }


            let wordIdC=wordIds[i+2];
            let wordSign4= _this.findSign(wordIdC)

            if(_this.isSign(wordSign4,field,act,noun)){
                let list=[wordIdA,wordIdB,wordIdC];
                signs.push({id:id,type:2,remarks:"生词:" +'words3',wordIdList:list,wordIdKey:wordIdC})
                i=i+2;
                continue
            }
            let list=[wordIdA,wordIdB];
            signs.push({id:id,type:1,remarks:"生词:" +'words2',wordIdList:list})
            i++;
            continue
        }
        return signs


    }
    /**
     *语句 分析
     */
    analysisRun(wordsIds){
        let _this=this;
        _this. ideaList=new RunOrderFile();        //实体
        _this.ideaList.addData(0,null,null,new Block());
       let  rod=  _this.ideaList.addData(0,0,null,new Row('1'));
        _this._analysisRun(wordsIds,0,rod);
        _this. ideaList.run(_this);
        return    _this. ideaList;
    }


    _analysisRun(wordsIds,n,pid){
        let _this=this;


        let ideaId=null;
        let structureId=null;
         let field ='68' ;//编码
        let act = '65' ;//语句
        let idea ='62';//分析
        let idea2='60'; //结构
        let rod=null;
        let rpid=null;
        for(let i=n;i<wordsIds.length;i++){
            let  wordsId=wordsIds[i].wordsId?wordsIds[i].wordsId:wordsIds[i].wordIdKey;
            let wordSign= _this.findSign(wordsId);

            //查看 指令 如果有指令就使用指令中的上下文，如果没有就使用全局上下文
            let ideaType=  _this.findIedaType(wordSign,field,act,idea);
            /**
             * 1 动词
             * 2 结构
             * 3 名词
             */
            if(ideaType==1){ //动词
                        let pid3=rod;
                        if(rod===null){
                            pid3=pid;
                        }
                       let id= _this.ideaList.addData(0,null,null,new Block()); //动词  实体
                        rod=  _this.ideaList.addData(0,0,null,new Row(null,null,id,'1'));// 添加一个 连接
                        _this.linkModify(pid3,1,rod) ;//


                        _this. ideaList.addData(0,id,null,new Row(wordsId,rod,'1')); //修改实体 第一行的 属性
                        let words1=wordsIds[i+1].wordsId;;
                        let wordSign1= _this.findSign(words1);
                        let ideaType2=  _this.findIedaType(wordSign1,field,act,idea);
                       if(ideaType2 ===1){ //动词

                           continue;
                       } else if( ideaType2 ==2){ //结构
                           continue;
                       }else { // 名词
                           pid3=rod;
                           let readlId = _this.ideaList.addData(0,null,null,new Block());//动词  实体 (依赖)
                           rod=  _this.ideaList.addData(0,0,null,new Row(null,null,readlId,'1'));// 添加一个 连接
                           _this.linkModify(pid3,1,rod) ;//

                           while (i<wordsIds.length-1&&ideaType2!=2){ // 不等于 结构

                               _this.ideaList.addData(0,readlId,null,new Row(words1,ideaType2));
                               i++;
                               words1=  wordsIds[i].wordsId?wordsIds[i].wordsId:wordsIds[i].wordIdKey;
                               wordSign1= _this.findSign(words1);
                               ideaType2=  _this.findIedaType(wordSign1,field,act,idea);
                           }
                           if(ideaType==2){
                               i--;
                           }
                           continue
                       }
            }else if(ideaType==2) { //结构
                    let pid3=rod;
                    if(rod===null){
                        pid3=pid;
                    }


                        //获取结构信息
                        let runType=  _this.findIedaType(wordSign,field,act,idea2);


                    if(runType=='1'){  //同级
                        rod=  _this.ideaList.addData(0,0,null,new Row('1'));// 添加一个 连接
                        _this.linkModify(pid3,0,rod) ;//
                        continue
                    }else if(runType=='2'){
                        pid3=  _this.ideaList.addData(0,0,null,new Row('1'));// 添加一个 连接
                        _this.linkModify(rod,1,pid3) ;//
                        rod=pid3;
                        i=_this._analysisRun(wordsIds,i,pid3);  //开启下级

                        continue
                    }else if(runType=='3'){
                         //获取 本rod的 pid
                        // 判断下一个词是 在不在这个pid 下面
                        // 在   平级
                        /// 在不在 查找函数pid
                        // 在
                        // 不在 函数pid为0
                        //为0    函数pid 子函数 最后一位
                        //不为 0 返回
                        if(pid==0){
                            let r=_this.seekLastSon(0);
                            if(r==null){ //等于空就添加一个儿子
                                rod=  _this.ideaList.addData(0,0,null,new Row('1'));// 添加一个 连接
                                _this.linkModify(0,1,rod) ;//
                            }else {
                                rod=  _this.ideaList.addData(0,0,null,new Row('1'));// 添加一个 连接
                                _this.linkModify(r,0,rod) ;//
                            }
                            continue
                        }else {
                            return i;
                        }
                        continue
                    }else {
                        return i;
                    }

            }else { //名词

                let pid3=rod;
                if(rod===null){
                    pid3=pid;
                }
                let readlId = _this.ideaList.addData(0,null,null,new Block());//动词  实体 (依赖)

                _this.linkModify(pid3,3,readlId) ;//数据指向自己


                while (i<wordsIds.length-1&&ideaType!=2){ // 等于 结构
                    _this.ideaList.addData(0,readlId,null,new Row(wordsId,ideaType))
                   i++
                    wordsId=wordsIds[i].wordsId?wordsIds[i].wordsId:wordsIds[i].wordIdKey;
                    let wordSign1= _this.findSign(wordsId);
                    ideaType=  _this.findIedaType(wordSign1,field,act,idea);
                }
                if(ideaType==2){
                    i--;
                }
                continue;
            }


        }



    }

    /**
     * 查找最后一个儿子
     * @param pid
     * @returns {*}
     */
    seekLastSon(pid){
        let _this=this;
        let list=_this.ideaList.list[0].list;
        let r=list[pid].find(2);
        let l=null;
        if(r!==null){
            l=list[r].find(1);
            while (l!=null) {
                let   p=list[l].find(1);
                if(p!=null) {
                    l=p;
                }else {
                    return l;
                }
            }
            return r;
        }
        return null;
    }


    /**
     * 修改 树的数据
     * @param rowId
     * @param linkId
     * @param value
     */
    linkModify(rowId,linkId,value){
        let _this=this;
        _this. value=value;
        _this.key=linkId;
        _this.ideaList.findData(0,0,rowId,_this.modify.bind(this)) ;//修改  指向 自己
    }
    /**
     *
     * @param FileId
     * @param BlockId
     * @param RowId
     * @param dataThis
     */
    modify(FileId,BlockId,RowId,dataThis){

        dataThis.list[this.key] =this.value;
    }



    /**
     * 获取 命令类型  结构    动词  对象
     * 1 动词
     * 2 结构
     * 3 名词
     * @param field
     * @param act
     * @param idea
     * @returns {*}
     */
    findIedaType(wordSign,field,act,idea){
        for(let l=0 ;l<wordSign.list.length;l++) {
            let row =wordSign.list[l];
            let res=[];
            if(row.isValue(1,field)) res.push(1);
            if(row.isValue(2,act)) res.push(1)
            if(row.isValue(4,idea)) res.push(1)
            if (res.length==3) {
                return row.find(3)
            }
        }

        return null;
    }

    /**
     * 生成数据 结构 名词 动词 主词
     *
     * 结构
     * 111 111 111 1  有条件跳转
     * 111 111 111 0  无条件跳转
     *
     */

    /**
     * 生成数据 结构 名词 动词 主词
     */
    createData2(words ){
        let _this=this;
        let field='27' ; //转换
        let act='27' ; //代码field,act,
        let verb='11' ;// 动词
        let noun='11' ;// 名词
        let structure='11' ;// 结构

        let zhuyu='';
        let caozuo='';


            if(_this.isComm(_this.comm)){
                _this .comms.push(_this.comm)
                _this. comm =new Array();
            }


            if(_this.comm[3]){
                zhuyu=_this.comm[3]
            }else {
                zhuyu=field
            }
            if(_this.comm[2]){
                caozuo=_this.comm[2]
            }else {
                caozuo=act
            }


            let isVerb=_this.isSign(words,zhuyu,caozuo,verb);  //动词
            let isNoun=_this.isSign(words,zhuyu,caozuo,noun); //名词
            let isStructure =_this.isSign(words,zhuyu,caozuo,structure); //结构

            if(isVerb &&!_this.comm[3]){ //动词 创建一个动作
                _this.comm[2]=words
                return;
            }

            if(isStructure){
                comm[0]=wordsIds
                return;
            }
            if(isNoun||!_this.comm[3]){
                _this.comm[1]=wordsIds
                return
            }else {
                _this.comm[3]=wordsIds
                return
            }
    }



    /**
     * 语句判断
     */
    isComm(wordSign, field,act,idea){

        for(let l=0 ;l<wordSign.list.length;l++) {
            let row =wordSign.list[l];
            let res=[];
            if(row.isValue(1,field)) res.push(1);
            if(row.isValue(2,act)) res.push(1)
            if(row.isValue(4,idea)) res.push(1)
            if (res.length==3) {
              return row.find(3)
            }
        }

        return null;


    }

    /**
     * 重新断言
     * @param stack
     * @returns {*}
     */
   breakSgain(stack){
        return stack;
   }
    /**
     * 检查栈
     * @param stack
     * @returns {boolean}
     */
    checkStack(stack){

        return true ;
    }

    //查询是不是词
    isWords(wordIdA,wordIdB){
        let words= new Row( wordIdA,wordIdB,null,3)

        let rowId= this.findEmptyId(words);
        if(rowId==null){
            return false;
        }
        return true;
    }
    //查询是不是的ID
    findWrodsId(wordIdA,wordIdB){
        let words= new Row( wordIdA,wordIdB,null,3)

        let rowId= this.findEmptyId(words,null,'empty');
        return rowId;
    }

    /**
     * 检查是否标记
     * @param wordSign
     */
    isSign(wordSign,field,act,idea){
        /**
         *  数字  digit
         *  符号 other
         *  单位 unit
         *
         * @type {Array}
         */
        if(wordSign){
            for(let l=0 ;l<wordSign.list.length;l++) {
                let row =wordSign.list[l];
                let res=[];
                if(row.isValue(1,field)) res.push(1);
                if(row.isValue(2,act)) res.push(1)
                if(row.isValue(4,idea)) res.push(1)
                if (res.length==3) {
                    if(row.isValue(3,'1')) return true
                }
            }
        }


        return false;
    }

    /**
     * 查找字符 的标记
     * @param wordId
     * @returns {null}
     */
    findSign(wordId){
        return this.findReal(null,wordId)
    }

    /**
     * 存储
     */
    runSave(file){
        return file;
    }

    /**
     * 输出
     * @param file
     */
    runOut(file){
        return file;
    }
}

